﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tanmia.Basis.Data
{
    /// <summary>
    /// يتمثل كافة الإمكانيات التي يمكن أن تتم على قاعدة البيانات بواسطة فئات نواة البرنامج
    /// </summary>
    /// <typeparam name="T">إحدى فئات نواة البرنامج التي نريد التعامل مع مستودع بياناتها</typeparam>
    public interface IRepository<T>
    {
        /// <summary>
        /// يقوم بحفظ الكائن في قاعدة البيانات, ثم يقوم بإعادة الكائن بعد أن تم تعبئته من قاعدة البيانات من جديد
        /// </summary>
        /// <param name="entity">الكائن الذي نريد حفظه</param>
        /// <returns>الكائن المحفوظ في قاعدة البيانات</returns>
        /// <exception cref="ConstraintViolationException">which is raised from the Database according to the constraint violation value.</exception>
        T Save(T entity);

        /// <summary>
        /// يقوم بتعديل السطر المقابل للكائن في قاعدة البيانات, وإعادة الكائن بعد أن تم تعبئته من قاعدة البيانات من جديد
        /// </summary>
        /// <param name="entity">الكائن الذي نريد تعديله</param>
        /// <returns>الكائن المحفوظ في قاعدة البيانات</returns>
        T Update(T entity);

        /// <summary>
        /// يقوم بحذف الكائن الممر من قاعدة البيانات
        /// </summary>
        /// <param name="entity">الكائن الذي نريد حذفه</param>
        void Delete(T entity);

        /// <summary>
        /// يقوم بإعادة كائن من قاعدة البيانات وذلك حسب رقم تعريفه.
        /// </summary>
        /// <param name="entityID">رقم تعريف الكائن الذي نريد إستعادته</param>
        /// <returns>الكائن المستعاد من قاعدة البيانات</returns>
        T Get(int entityID);

        /// <summary>
        /// يقوم بإعادة كافة الكائنات المحفوظة في قاعدة البيانات
        /// </summary>
        /// <returns>قائمة بكافة الكائنات</returns>
        /// <remarks>أفضل عدم إستخدام هذا التابع وذلك يرجع لأسباب تتعلق بحجم البيانات الكبير الممكن أن يقوم بإعادته</remarks>
        IList<T> Gets();

        /// <summary>
        /// يقوم بتطبيق المقايس الممررة له على البيانات الموجودة في قاعدة البيانات ويعيد النتيجة
        /// </summary>
        /// <param name="propertyValuepairs">مجموعة من أسماء الخصائص والقيم التي نريد تطبيقها على قاعدة البيانات</param>
        /// <returns>قائمة بكافة الكائنات التي تحقق المقياس</returns>
        IList<T> Search(Dictionary<string, object> propertyValuepairs);

        IList<T> Gets(Specification<T> specs);
    }
}
